/**
 *	1、处理后端返回的用户菜单列表
 *	2、生成后台页面的路由
 */

//导入静态路由和动态路由
import { constantRoutes, asyncRoutes } from "@/router"

import Layout from '@/layout'

const state = {
	routes: [], //用户登录后能访问的所有路由
	addRoutes: [] //需要添加的路由
}

//使用vuex维护路由
const mutations = {
  SET_ROUTERS: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
	//获取用户菜单
	getMenus({ commit, state }, data){
		return new Promise((resolve, reject) => {
			//将路由转换，并且存到vuex中
			let accessedRouters = convertRouter(data)
			commit('SET_ROUTERS', accessedRouters)
			resolve(accessedRouters)
		}).catch(error => {})
	},
}

//判断菜单下是否有子级菜单
function hasChild(rows, parentId){
	for (let i = 0; i < rows.length; i++) {
	    if (rows[i].id === parentId){
			return true
		}
	}
	return false
}

//将菜单列表转为router形式
function convertRouter(array){
	//创建节点数组
	let nodes = []
	//获取顶级节点
	for (let i = 0; i < array.length; i++){
		//取出第一条数据
		let row = array[i]
		//判断是否有子级菜单
		if(!hasChild(array, row.parentId)){
			//创建路由节点
			let route = {
				path: row.path, // 路由地址
				hidden: row.hidden, // 全部true就行，如果后端没配
				component: Layout, //组件地址
				name: row.menuName, // 路由名称
				meta: { title: row.menuName, icon: row.icon }, // title就是显示的名字
				id: row.id, // 路由的id
				redirect: 'noredirect'
			}
			//将路由节点添加到数组中
			nodes.push(route)
		}
	}
	//将类数组转为数组
	let menus = Array.from(nodes)
	//处理子节点菜单
	while(menus.length){
		//数组第一个路由
		let node = menus.shift()
		// 获取子节点
		for (let i = 0; i < array.length; i++) {
			let row = array[i]
			//查找父级节点
			if (row.parentId === node.id) {
				//创建子级菜单
				 let child = {
					path: row.path,
					name: row.menuName,
					hidden: row.hidden,
					component: (resolve) => require([`@/${row.component}`], resolve), //采用懒加载方式加载组件
					meta: { title: row.menuName, icon: row.icon },
					id: row.id
				}
				
				//判断该父级菜单是否已经有子级菜单的数组
				if(node.children){
					//有则继续添加
					node.children.push(child)
				}else{
					//没有则创建新的子级菜单数组
					node.children = [child]
				}
				menus.push(child)
			}
		}
	}
	return nodes
}

//暴露方法
export default {
  namespaced: true,
  state,
  mutations,
  actions
}